package com.andooco.dataq.service.func;

import com.alibaba.fastjson.JSON;
import com.andooco.dataq.service.config.SessionConfig;
import com.andooco.dataq.service.func.dto.FuncDto;
import com.andooco.dataq.util.CSVUtils;
import com.andooco.dataq.util.CommonConstants;
import com.andooco.dataq.util.StatEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.function.Predicate;

/**
 * 功能块操作管理
 *
 * @author andooco
 * 20201126
 */
@Slf4j
@Service("FuncService")
public class FuncService {

    @Autowired
    private SessionConfig sessionConfig;

    /**
     * 查询功能块列表
     * 先在缓存中查询，如果缓存中没有功能块信息，加载功能块CSV文件到缓存中
     *
     * @param funcName
     * @return
     */
    public List<FuncDto> findFuncList(String funcName) throws UnsupportedEncodingException {
        log.info("进入FuncService 查询功能块入口");
        List<FuncDto> funcDtos = getFuncDtosCached();
        if (StringUtils.isBlank(funcName)) {
            return funcDtos;
        } else {
            //定义filters
            Predicate<FuncDto> strFilter = (funcDto) -> (funcDto.getFuncName().contains(funcName));
            List<FuncDto> funcDtoList = new ArrayList<>();
            funcDtos.stream()
                    .filter(strFilter)
                    .forEach((strlist) -> funcDtoList.add(strlist));
            return funcDtoList;
        }
    }

    /**
     * 获取功能块缓存
     *
     * @return
     * @throws UnsupportedEncodingException
     */
    public List<FuncDto> getFuncDtosCached() throws UnsupportedEncodingException {
        List<FuncDto> funcDtos = sessionConfig.embeddedHazelcast().getList(CommonConstants.funcList);
        if (funcDtos == null || funcDtos.size() == 0) {
            //如果缓存jdbc为空，加载功能块CSV文件
            List<String[]> datas = CSVUtils.importCsv(CommonConstants.DATA_ROOT_PATH, CommonConstants.FUNC_PATH);
            convertsToJdbc(datas, funcDtos);
        }
        return funcDtos;
    }

    /**
     * 保存/更新功能块列表【funcUid不为空则为更新操作】
     * 先在缓存中查询，如果缓存中没有功能块信息，加载功能块CSV文件到缓存中
     *
     * @param funcDtoInput
     * @return
     */
    public String saveOrUpdateFuncList(FuncDto funcDtoInput) throws UnsupportedEncodingException {
        log.info("进入FuncService 保存/更新功能块入口:{}", JSON.toJSONString(funcDtoInput));
        //保存数据到csv文件中
        String[] dataList = new String[3];
        List<FuncDto> funcDtos = getFuncDtosCached();

        if(StringUtils.isNotBlank(funcDtoInput.getFuncUid())){
            log.info("进入更新逻辑");
            List<String[]> dataListFile = new ArrayList<>();
            for (int i = 0; i < funcDtos.size(); i++) {
                FuncDto funcDto = funcDtos.get(i);
                if(funcDto.getFuncUid().equals(funcDtoInput.getFuncUid())){
                    funcDto.setFuncContent(funcDtoInput.getFuncContent());
                    funcDto.setFuncName(funcDtoInput.getFuncName());
                }
                String[] strings = new String[3];
                convertsToList(strings, funcDto);
                dataListFile.add(strings);
            }
            funcDtos.clear();
            log.info("更新csv文件数据：{}", JSON.toJSONString(dataListFile));
            //使用覆盖模式
            CSVUtils.writeDataListToCsvFile(CommonConstants.DATA_ROOT_PATH, CommonConstants.FUNC_PATH, dataListFile, false, CSVUtils.HEAD_ARR_FUNC);
        } else {
            log.info("进入新增逻辑");
            //判断连接名是否有重复
            for (FuncDto funcDto1 : funcDtos) {
                if (funcDto1.getFuncName().equals(funcDtoInput.getFuncName())) {
                    return "功能名重复，操作失败";
                }
            }
            funcDtoInput.setFuncUid(UUID.randomUUID().toString().replaceAll("-", ""));
            //新增数据到缓存中
            funcDtos.add(funcDtoInput);
            log.info("追加数据到csv文件中：{}", JSON.toJSONString(funcDtoInput));
            convertsToList(dataList, funcDtoInput);
            CSVUtils.writeDataToCsvFile(CommonConstants.DATA_ROOT_PATH, CommonConstants.FUNC_PATH, dataList, CSVUtils.HEAD_ARR_FUNC);
        }

        return StatEnum.SUCCESS.getCode();
    }

    /**
     * 删除功能块
     *
     * @param funcUid
     * @return
     */
    public String delFuncList(String funcUid) throws Exception {
        log.info("进入FuncService 删除功能块入口");
        //保存数据到csv文件中
        List<FuncDto> funcDtos = getFuncDtosCached();
        //判断连接名是否有重复
        //定义filters
        Predicate<FuncDto> strFilter = (funcDto) -> (!funcDto.getFuncUid().equals(funcUid));
        List<FuncDto> funcDtoList = new ArrayList<>();
        funcDtos.stream()
                .filter(strFilter)
                .forEach((strlist) -> funcDtoList.add(strlist));
        if (funcDtos.size() == funcDtoList.size()) {
            log.info("未找到匹配数据库");
            return StatEnum.FAIL.getCode();
        }
        funcDtos.clear();
        List<String[]> dataListFile = new ArrayList<>();
        for (int i = 0; i < funcDtoList.size(); i++) {
            String[] strings = new String[3];
            convertsToList(strings, funcDtoList.get(i));
            dataListFile.add(strings);
        }
        log.info("更新csv文件数据：{}", JSON.toJSONString(dataListFile));
        //使用覆盖模式
        CSVUtils.writeDataListToCsvFile(CommonConstants.DATA_ROOT_PATH, CommonConstants.FUNC_PATH, dataListFile, false, CSVUtils.HEAD_ARR_FUNC);
        return StatEnum.SUCCESS.getCode();
    }

    /**
     * 把csv文件读取的内容转成bean对象
     *
     * @param datas
     * @param funcDtos
     */
    public void convertsToJdbc(List<String[]> datas, List<FuncDto> funcDtos) throws UnsupportedEncodingException {
        for (int i = 0; i < datas.size(); i++) {
            String[] data = datas.get(i);
            FuncDto funcDto = new FuncDto();
            funcDto.setFuncName(URLDecoder.decode(data[0], "utf-8"));
            funcDto.setFuncContent(URLDecoder.decode(data[1], "utf-8"));
            funcDto.setFuncUid(data[2]);
            funcDtos.add(funcDto);
        }
    }

    /**
     * 把数据转换为数组
     *
     * @param data
     * @param funcDto
     */
    public void convertsToList(String[] data, FuncDto funcDto) throws UnsupportedEncodingException {
        data[0] = URLEncoder.encode(funcDto.getFuncName(), "utf-8");
        data[1] = URLEncoder.encode(funcDto.getFuncContent(), "utf-8");
        data[2] = funcDto.getFuncUid();
    }
}
